package com.pgytesting.mobilecertpay.util;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.pgytesting.mobilecertpay.entity.NaSecret;
import lombok.extern.slf4j.Slf4j;

import java.io.FileReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class UtilMethod {


    /**
     * @param @param
     * @return @return
     * @throws
     * @Title: MapToJson
     * @Description: TODO(Map转json对象)
     * @author sunbo@pgytesting.cn
     * @date 2019/5/6 17:49
     */
    public static JSONObject MapToJson(Map param) {
        return new JSONObject(param);
    }


    /**
     * @param @param
     * @return @return
     * @throws
     * @Title: JsonToString
     * @Description: TODO(json转换为字符串)
     * @author sunbo@pgytesting.cn
     * @date 2019/5/6 17:52
     */
    public static String JsonToString(JSONObject param) {
        return param.toJSONString();
    }

    /**
     * @param @param
     * @return @return
     * @throws
     * @Title: JsonToMap
     * @Description: TODO(json对象转换为map)
     * @author sunbo@pgytesting.cn
     * @date 2019/5/6 17:53
     */
    public static Map JsonToMap(JSONObject param) {
        return param;
    }


    /**
     * @param @param
     * @return @return
     * @throws
     * @Title: StringToJson
     * @Description: TODO(字符串转换json对象)
     * @author sunbo@pgytesting.cn
     * @date 2019/5/6 17:54
     */
    public static JSONObject StringToJson(String param) {
        return JSONObject.parseObject(param);
    }

    /**
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: randomCode
     * @Description: TODO(每次调用生成一个6位随机数)
     */
    public static String randomCode() {
        Random rand = new Random();
        int randNumber = rand.nextInt(1000000 - 100000 + 1) + 100000;
        return String.valueOf(randNumber);
    }

    /**
     * @param @return 设定文件
     * @return Long    返回类型
     * @throws
     * @Title: unixString
     * @Description: TODO(获取系统当前时间戳)
     */
    public static Long unixLong() {
        return System.currentTimeMillis();
    }

    /**
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: getdingdan
     * @Description: TODO(生成唯一识别的流水号)
     */
    public static String getdingdan() {
        Date date = new Date();
        SimpleDateFormat sf;
        sf = new SimpleDateFormat("yyyyMMdd");
        return sf.format(date);
    }



    /**
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: getdingdan
     * @Description: TODO(获取当前时间)
     */
    public static String getTime() {
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat();
        sf = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
        return sf.format(date);
    }

    /**
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: getdingdan
     * @Description: TODO(时间戳转换为时间)
     */
    public static String getTime(Long date) {
        SimpleDateFormat sf = new SimpleDateFormat();
        sf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        return sf.format(date);
    }


    /**
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: uuidMd5Encryption
     * @Description: TODO(生成唯一标识的UUID)
     */
    public static String getUniqueCode() {
        return String.valueOf(java.util.UUID.randomUUID());
    }


    public static void main(String[] args) {
        System.out.println(getUniqueCode());
    }
    /**
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: md5Encryption
     * @Description: TODO(32位加密加盐方法)
     */
    public static String md5Encryption(String passWord) {
        try {
            // 得到一个信息摘要器
            MessageDigest digest = MessageDigest.getInstance("md5");
            byte[] result = digest.digest(passWord.getBytes());
            StringBuffer buffer = new StringBuffer();
            // 把每一个byte 做一个与运算 0xff;
            for (byte b : result) {
                // 与运算
                int number = b & 0xff;// 加盐
                String str = Integer.toHexString(number);
                if (str.length() == 1) {
                    buffer.append("0");
                }
                buffer.append(str);
            }
            // 标准的md5加密后的结果
            return buffer.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }



    /**
     * @param @param  unix
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: getUnixToTime
     * @Description: TODO(将秒转换为时间)
     */
    public static String getUnixToTime(Long unix) {
        Long unix1;
        Long unix2;
        unix1 = unix / 60;
        unix2 = unix1 / 60;
        log.info("执行转换方法：将" + unix + "秒转换为" + unix2 + ":" + unix1 % 60 + ":" + unix % 60);
        StringBuffer time = new StringBuffer();
        if (unix >= 3600) {
            time.append(unix2 + ":");
        }
        if (unix >= 60) {
            time.append(unix1 % 60 + ":");
        }
        return String.valueOf(time.append(unix % 60));
    }


    /**
     * 利用正则表达式判断字符串是否是数字
     *
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }


    /**
     * @param @param  num
     * @param @return 设定文件
     * @return double    返回类型
     * @throws
     * @Title: getTwoDecimal
     * @Description: TODO(保留两位小数 ， 四舍五入)
     */
    public static Double getTwoDecimal(Double num) {
        DecimalFormat dFormat = new DecimalFormat("#.00");
        String yearString = dFormat.format(num);
        Double temp = Double.valueOf(yearString);
        return temp;
    }


    /**
     * 获得该月最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month - 1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime());
        return lastDayOfMonth;
    }


    /**
     * @param @param 至少银行卡前六位
     * @return @return Map<String,Object>
     * @throws
     * @Title: getBackCardInf
     * @Description: TODO(读取json文件对银行卡进行银行卡信息查询)
     * @author sunbo@pgytesting.cn
     * @date 2019/5/8 22:02
     */
    public static Map<String, Object> getBackCardInf(String backNumber) {
        if (backNumber.length() < 6)
            return null;
        JsonObject jsonObject = getReadJson();
        JsonObject jsonObject2 = (JsonObject) (backNumber.length() == 6 ? jsonObject.get(backNumber) : jsonObject.get(backNumber.substring(0, 6)));
        Map<String, Object> resultMap = new LinkedHashMap<>();
        log.info("进行银行信息填入");
        resultMap.put("bankCardNo", backNumber);
        if (jsonObject2 != null) {
            resultMap.put("bankName", jsonObject2.get("issuer").getAsString());
            resultMap.put("bankCode", jsonObject2.get("issuerCode").getAsString());
//            resultMap.put("cardName",jsonObject2.get("cardName").getAsString());
            resultMap.put("cardType", jsonObject2.get("bankCardType").getAsString().equals("借记卡") ? 1 : 2);
//            resultMap.put("length",jsonObject2.get("length").getAsInt());
        } else {
            resultMap.put("cardType", "UNKNOW");
            resultMap.put("bankName", "");
            resultMap.put("bankCode", "");
        }
        return resultMap;
    }
    /**
     * @param @param 至少银行卡前六位
     * @return @return Map<String,Object>
     * @throws
     * @Title: getBackCardList
     * @Description: TODO(读取json文件对银行卡进行银行卡信息查询)
     * @author sunbo@pgytesting.cn
     * @date 2019/5/8 22:02
     */
    public static List<Map<String,Object>> getBackCardList() {
        log.info("获取到json文本的数据");
        JsonObject jsonObject = getReadJson();
        Map<String ,Object> map = new HashMap<>();
        log.info("对数据进行去重处理");
        for (String s : jsonObject.keySet()) {
            String key = jsonObject.getAsJsonObject(s).get("issuerCode").getAsString();
            String values = jsonObject.getAsJsonObject(s).get("issuer").getAsString();
            if (isNumeric(key) && isEmpty(key)){
                continue;
            }
            map.put(key,values);
        }
        log.info("对数据进行最终迭代");
        List<Map<String,Object>> resultList = new LinkedList<>();
        for (String s : map.keySet()) {
            Map<String ,Object> reultMap = new HashMap<>();
            reultMap.put("bankCode",s);
            reultMap.put("bankName",map.get(s));
            resultList.add(reultMap);
        }
        return resultList;
    }


    /**
     * @Title: getReadJson
     * @Description: TODO(进行json文件读取)
     * @param @param
     * @return @return
     * @author sunbo@pgytesting.cn
     * @throws
     * @date 2019/5/23 19:57
     */
    public static JsonObject getReadJson() {
        JsonParser jsonParser = new JsonParser();
        JsonObject jsonObject;
        try {
            log.info("进行静态数据文件的绝对路径获取");
            String jsonFilePath = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "static/BackCardBin.json";
            log.info("获取到的路径为：" + jsonFilePath);
            log.info("进行银行信息数据格式化为json");
            jsonObject = (JsonObject) jsonParser.parse(new FileReader(jsonFilePath));
        } catch (Exception e) {
            log.error("BackCardBin.json文件读取异常");
            return null;
        }
        return jsonObject;
    }


    /**
     * 获取公钥私钥，并生成系统时间
     * @param naSecret
     * @return
     */
    public static NaSecret getKey(NaSecret naSecret) {
        log.info("公钥私钥为空，则进行公钥私钥生成");
        try {
            Map<String, String> keyMap = RSAUtils.createKeys();
            naSecret.setPublicKey(keyMap.get("publicKey"));
            naSecret.setPrivateKey(keyMap.get("privateKey"));
            naSecret.setSystemTime(UtilMethod.unixLong());
            log.info("公钥私钥获取成功");
        } catch (Exception e) {
            log.info("获取公钥私钥异常" + e.getMessage());
        }
        return naSecret;
    }


    /**
     * 字符串判断方法
     * @param s 字符串
     * @return 如果为""或者 null则返回true
     */
    public static boolean isEmpty(String s) {
        return s == null || s.length() == 0 || "null".equals(s);
    }





}
